package com.nervenets.shopping.controller.order;

import com.nervenets.general.entity.ResponseResult;
import com.nervenets.general.jwt.aspect.JwtRole;
import com.nervenets.general.jwt.aspect.JwtSecurity;
import com.nervenets.general.redis.RedisSyncLocker;
import com.nervenets.general.service.RedisService;
import com.nervenets.general.utils.JodaUtils;
import com.nervenets.general.web.BaseController;
import com.nervenets.shopping.controller.order.params.BonusStatisticsParams;
import com.nervenets.shopping.controller.order.vo.BonusStatisticsVo;
import com.nervenets.shopping.hibernate.domain.common.GlobalRuleSetting;
import com.nervenets.shopping.hibernate.domain.order.BonusSharing;
import com.nervenets.shopping.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;

@Slf4j
@Api(value = "分红管理接口v1", tags = "分红管理相关接口")
@RestController
@RequestMapping("/api/bonus")
@JwtRole(group = "orders", groupName = "订单管理", function = "bonus", functionName = "分红管理", queue = 204)
public class AllBonusController extends BaseController {
    @Resource
    private BonusSharingService bonusSharingService;
    @Resource
    private GroupBuyOrderUserService groupBuyOrderUserService;
    @Resource
    private GroupBuyOrderService groupBuyOrderService;
    @Resource
    private UserService userService;
    @Resource
    private GlobalRuleService globalRuleService;
    @Resource
    private RedisService redisService;
    @Resource
    private RedisSyncLocker<ResponseEntity<ResponseResult<BonusSharing>>> redisSyncLocker;

    @ApiOperation(value = "统计信息")
    @PostMapping("/statistics")
    public ResponseEntity<ResponseResult<BonusStatisticsVo>> statistics(@Valid @RequestBody BonusStatisticsParams params) throws Exception {
        long performance = groupBuyOrderService.sumOfBonusByTime(params.getStartTime(), params.getEndTime()).longValue();
        long totalPeople = userService.count((predicates, root, query, builder) -> {
            predicates.add(builder.isTrue(root.get("inviter")));
            predicates.add(builder.isTrue(root.get("enable")));
        });
        return successMessage(BonusStatisticsVo.builder()
                .performance(performance)
                .totalPeople(totalPeople)
                .ratio(100)
                .bonus(performance)
                .preBonus(totalPeople > 0 ? performance / totalPeople : 0)
                .executed(bonusSharingService.count((predicates, root, query, builder) -> {
                    predicates.add(builder.equal(root.get("year"), params.getYear()));
                    predicates.add(builder.equal(root.get("week"), params.getWeek()));
                }) > 0)
                .build());
    }

    @ApiOperation(value = "分红")
    @PostMapping("/sharing")
    @JwtSecurity(permission = "sharing", permissionName = "分红")
    public ResponseEntity<ResponseResult<BonusSharing>> sharing(@Valid @RequestBody BonusStatisticsParams params) throws Exception {
        if (!redisService.canProceedCustom("BONUS_SHARING", 60)) {
            return errorMessage("为保障资金安全，一分钟内，只能提交一次分红。");
        }
        return redisSyncLocker.keyLock(String.format("BONUS_SHARING_%s_%s", params.getYear(), params.getWeek()), () -> {
            if (bonusSharingService.count((predicates, root, query, builder) -> {
                predicates.add(builder.equal(root.get("year"), params.getYear()));
                predicates.add(builder.equal(root.get("week"), params.getWeek()));
            }) > 0) return errorMessage("当前周已执行分红，无须重复分红。");

            if (params.getEndTime() >= JodaUtils.getTimestamp()) return errorMessage("本周还未结束，无法发放分红。");
            long performance = groupBuyOrderService.sumOfBonusByTime(params.getStartTime(), params.getEndTime()).longValue();

            if (performance <= 0) return errorMessage("业绩金额不足，无法执行分红。");

            return successMessage(bonusSharingService.save(BonusSharing.builder()
                    .year(params.getYear())
                    .week(params.getWeek())
                    .totalMoney(performance)
                    .ratio(100)
                    .finished(false)
                    .build()));
        });
    }
}
